#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
RocketMQ 生产者演示
演示如何发送消息到 RocketMQ
"""

import time
import json
import logging
from rocketmq.client import Producer, Message
from config import ROCKETMQ_CONFIG, MESSAGE_CONFIG, LOGGING_CONFIG, DEMO_CONFIG, check_config, configure_rocketmq

# 配置日志
logging.basicConfig(
    level=getattr(logging, LOGGING_CONFIG["level"]), 
    format=LOGGING_CONFIG["format"]
)
logger = logging.getLogger(__name__)


class RocketMQProducer:
    """RocketMQ 生产者类"""
    
    def __init__(self):
        self.producer = None
        self.namesrv_addr = ROCKETMQ_CONFIG["namesrv_addr"]
        self.access_key = ROCKETMQ_CONFIG["access_key"]
        self.secret_key = ROCKETMQ_CONFIG["secret_key"]
        self.group_name = ROCKETMQ_CONFIG["producer_group"]
        self.topic = ROCKETMQ_CONFIG["default_topic"]
    
    def start(self):
        """启动生产者"""
        try:
            logger.info("=== 启动 RocketMQ 生产者 ===")
            logger.info(f"NameServer: {self.namesrv_addr}")
            logger.info(f"生产者组: {self.group_name}")
            logger.info(f"主题: {self.topic}")
            
            # 创建生产者
            self.producer = Producer(self.group_name)
            self.producer.set_name_server_address(self.namesrv_addr)
            self.producer.set_session_credentials(self.access_key, self.secret_key, "ALIYUN")
            
            # 启动生产者
            self.producer.start()
            logger.info("✓ 生产者启动成功")
            return True
            
        except Exception as e:
            logger.error(f"✗ 生产者启动失败: {e}")
            return False
    
    def send_message(self, message_data, tags=None, keys=None):
        """发送单条消息"""
        try:
            # 创建消息
            msg = Message(self.topic)
            
            # 设置消息内容
            if isinstance(message_data, dict):
                body = json.dumps(message_data, ensure_ascii=False)
            else:
                body = str(message_data)
            
            msg.set_body(body.encode(MESSAGE_CONFIG["encoding"]))
            
            # 设置消息标签
            if tags:
                msg.set_tags(tags)
            else:
                msg.set_tags(MESSAGE_CONFIG["default_tags"])
            
            # 设置消息键
            if keys:
                msg.set_keys(keys)
            
            # 发送消息
            send_result = self.producer.send_sync(msg)
            
            # 打印发送结果
            if DEMO_CONFIG["verbose"]:
                logger.info(f"✓ 消息发送成功")
                logger.info(f"  - MsgId: {send_result.msg_id}")
                logger.info(f"  - 内容: {body}")
                logger.info(f"  - 标签: {tags or MESSAGE_CONFIG['default_tags']}")
                logger.info(f"  - 键: {keys or 'N/A'}")
                
                # 兼容性处理
                if hasattr(send_result, 'offset'):
                    logger.info(f"  - 偏移量: {send_result.offset}")
                if hasattr(send_result, 'status'):
                    logger.info(f"  - 状态: {send_result.status}")
            
            return send_result
            
        except Exception as e:
            logger.error(f"✗ 消息发送失败: {e}")
            return None
    
    def send_batch_messages(self, message_list):
        """批量发送消息"""
        logger.info(f"=== 批量发送 {len(message_list)} 条消息 ===")
        
        success_count = 0
        for i, msg_data in enumerate(message_list, 1):
            try:
                result = self.send_message(
                    message_data=msg_data,
                    tags=f"batch_{i}",
                    keys=f"key_{i}"
                )
                if result:
                    success_count += 1
                
                # 消息间隔
                if i < len(message_list):
                    time.sleep(DEMO_CONFIG["message_interval"])
                    
            except Exception as e:
                logger.error(f"✗ 第 {i} 条消息发送失败: {e}")
        
        logger.info(f"批量发送完成: {success_count}/{len(message_list)} 成功")
        return success_count
    
    def shutdown(self):
        """关闭生产者"""
        if self.producer:
            self.producer.shutdown()
            logger.info("生产者已关闭")


def create_demo_messages():
    """创建演示消息"""
    messages = []
    
    # 不同类型的消息
    message_types = [
        {"type": "text", "content": "Hello RocketMQ!"},
        {"type": "json", "data": {"user": "demo", "action": "send"}},
        {"type": "number", "value": 42},
        {"type": "list", "items": [1, 2, 3, 4, 5]},
        {"type": "boolean", "flag": True},
    ]
    
    for i in range(DEMO_CONFIG["message_count"]):
        msg_type = message_types[i % len(message_types)]
        msg_data = {
            "id": i + 1,
            "timestamp": int(time.time()),
            "message": f"演示消息 #{i + 1}",
            "data": msg_type,
            "source": "python_demo"
        }
        messages.append(msg_data)
    
    return messages


def check_configuration():
    """检查配置"""
    missing_fields = check_config()
    if missing_fields:
        print(f"❌ 配置不完整，缺少: {', '.join(missing_fields)}")
        print("请先配置 RocketMQ 连接信息")
        
        if configure_rocketmq():
            print("✓ 配置完成，可以继续运行演示")
            return True
        else:
            print("❌ 配置失败，请重新运行程序")
            return False
    return True


def main():
    """主函数"""
    logger.info("开始 RocketMQ 生产者演示...")
    
    # 检查配置
    if not check_configuration():
        return
    
    # 创建生产者
    producer = RocketMQProducer()
    
    try:
        # 启动生产者
        if not producer.start():
            return
        
        # 创建演示消息
        messages = create_demo_messages()
        
        # 发送消息
        success_count = producer.send_batch_messages(messages)
        
        # 总结
        logger.info("=== 演示总结 ===")
        logger.info(f"总消息数: {len(messages)}")
        logger.info(f"成功发送: {success_count}")
        logger.info(f"失败数量: {len(messages) - success_count}")
        
        if success_count > 0:
            logger.info("✓ 生产者演示成功完成")
        else:
            logger.error("✗ 生产者演示失败")
            
    except KeyboardInterrupt:
        logger.info("用户中断演示")
    except Exception as e:
        logger.error(f"演示过程中发生错误: {e}")
    finally:
        producer.shutdown()


if __name__ == "__main__":
    main() 